package com.ternnetwork.workflow.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.ternnetwork.commons.model.http.BaseResponse;
import com.ternnetwork.workflow.dto.ProcessTaskQueryDto;
import com.ternnetwork.workflow.enums.messages.TaskMessages;
import com.ternnetwork.workflow.service.ProcessTaskService;
import com.ternnetwork.workflow.vo.HistoricTaskInstanceVo;
import com.ternnetwork.workflow.vo.TaskVo;



@Service
public class ProcessTaskServiceImpl implements ProcessTaskService {
	
	@Autowired
	private TaskService taskService;
	
	@Autowired
	private FormService formService;
	
	
	@Autowired
	private HistoryService historyService;
	
	
	/**
	 * 分页查询
	 * @param pageable
	 * @param dto
	 * @return
	 */
	@Override
	public BaseResponse findByPage(Pageable pageable,ProcessTaskQueryDto dto) {
		
		TaskQuery q=taskService.createTaskQuery();
		
		//流程定义名称
		if(!StringUtils.isEmpty(dto.getProcessDefinitionName())){
			q.processDefinitionNameLike(dto.getProcessDefinitionName());
		}
		//流程定义key
		if(!StringUtils.isEmpty(dto.getProcessDefinitionKey())){
			q.processDefinitionKeyLike(dto.getProcessDefinitionKey());
		}
		
		//查询个人待办任务
		if(!StringUtils.isEmpty(dto.getTaskAssignee())){
			q.taskAssignee(dto.getTaskAssignee());
		}
		
		//查询候选组任务 
		if(!StringUtils.isEmpty(dto.getTaskCandidateGroup())){
			q.taskCandidateGroup(dto.getTaskCandidateGroup());
		}
		//查询用户候选任务
		if(!StringUtils.isEmpty(dto.getTaskCandidateUser())){
			q.taskCandidateUser(dto.getTaskCandidateUser());
		}
		
	    int firstResult=Integer.valueOf(String.valueOf(pageable.getOffset()));
		
		int maxResult=pageable.getPageSize();
		
		long totalElements=q.count();
		
		List<Task> taskList=q.listPage(firstResult, maxResult);
		
		List<TaskVo> taskVoList=convertToTaskVo(taskList);
		
	    Map<String,Object> data=new HashMap<String,Object>(10);
			
   		data.put("content", taskVoList);
		
		data.put("totalElements", totalElements);
		
		BaseResponse baseResponse=new BaseResponse();
		
		baseResponse.setSccucess(data);
			
		return baseResponse;
	}
	
	
	private List<TaskVo> convertToTaskVo(List<Task> taskList){
		List<TaskVo> retVal=new ArrayList<TaskVo>();
		  for(Task t:taskList){
			  TaskVo taskVo=new TaskVo();
			  taskVo.setId(t.getId());
			  taskVo.setAssignee(t.getAssignee());
			  taskVo.setCreateTime(t.getCreateTime());
			  taskVo.setName(t.getName());
			  taskVo.setProcessInstanceId(t.getProcessInstanceId());
			  taskVo.setDueDate(t.getDueDate());
			  taskVo.setProcessDefinitionId(t.getProcessDefinitionId());
			  taskVo.setFormKey(t.getFormKey());
			  retVal.add(taskVo);
		  }
		return retVal;
	}
	
	/**
	 * 获取任务表单数据
	 * @param taskId
	 * @return
	 */
	@Override
	public BaseResponse getTaskFormData(String taskId) {
		
		TaskFormData formData = formService.getTaskFormData(taskId);
		
        BaseResponse baseResponse=new BaseResponse();
		
		baseResponse.setSccucess(formData);
			
		return baseResponse;
	} 
	
	/**
	 * 领取任务
	 * @param taskId
	 * @param userName
	 * @return
	 */
	@Override
	public BaseResponse claim(String taskId,String userName) {
		
		taskService.claim(taskId, userName);

        BaseResponse baseResponse=new BaseResponse();
		
        baseResponse.setSccucess();
		
		return baseResponse;
	}
	
	/**
	 * 完成任务,保存表单数据
	 * @param taskId
	 * @param map 表单数据
	 * @return
	 */
	@Override
	public BaseResponse complete(String taskId, Map<String, String[]> map) {
		Map<String, Object> variableLocalMap = new HashMap<String, Object>();
		Map<String, String> formDataMap = new HashMap<String, String>();
		Set<String> keyset = map.keySet();
		for (String key : keyset) {
			String[] values = map.get(key);
			String value = values[0];
			if (!key.equals("id")) {
				
				if ("true".equals(value)) {
					taskService.setVariableLocal(taskId, key, true);
				} else if ("false".equals(value)) {
					taskService.setVariableLocal(taskId, key, false);
				} else {
					taskService.setVariableLocal(taskId, key, value);
				}
				variableLocalMap.put(key, value);
				formDataMap.put(key, value);
			}
		}
		//保存表单数据
		formService.saveFormData(taskId, formDataMap);
		
		//执行任务完成
		taskService.complete(taskId,variableLocalMap);
		
	    BaseResponse baseResponse=new BaseResponse();
		
		baseResponse.setSccucess();
				
	   return baseResponse;
	}
	 @Override
	 public BaseResponse findHistoricTaskInstanceByPage(Pageable pageable,String processInstanceId) {
			
		    HistoricTaskInstanceQuery q= historyService.createHistoricTaskInstanceQuery();
		 
		 
		    q.processInstanceId(processInstanceId);
		 
		    q.orderByTaskCreateTime();
		    
		    q.asc();
		    
		    int firstResult=Integer.valueOf(String.valueOf(pageable.getOffset()));
			
			int maxResult=pageable.getPageSize();
			
			List<HistoricTaskInstance> historicTaskInstanceList =q.listPage(firstResult, maxResult);
			
			
			long totalElements=q.count();
		    
		    List<HistoricTaskInstanceVo> historicTaskInstanceVoList=convertToHistoricTaskInstanceVo(historicTaskInstanceList);

		    Map<String,Object> data=new HashMap<String,Object>(10);
			
	   		data.put("content", historicTaskInstanceVoList);
			
			data.put("totalElements", totalElements);
			
			BaseResponse baseResponse=new BaseResponse();
			
			baseResponse.setSccucess(data);

			return baseResponse;
			
	}


	/**
	 * 转换为视图对象列表 
	 * @param historicTaskInstanceList
	 * @return
	 */
	private List<HistoricTaskInstanceVo> convertToHistoricTaskInstanceVo(List<HistoricTaskInstance> historicTaskInstanceList) {
		
		List<HistoricTaskInstanceVo> historicTaskInstanceVoList=new ArrayList<HistoricTaskInstanceVo>(50); 
		
		for(HistoricTaskInstance historicTaskInstance:historicTaskInstanceList) {
			
			HistoricTaskInstanceVo historicTaskInstanceVo=new HistoricTaskInstanceVo();
			
			historicTaskInstanceVo.setAssignee(historicTaskInstance.getAssignee());
			
			historicTaskInstanceVo.setCreateTime(historicTaskInstance.getCreateTime());
			
			historicTaskInstanceVo.setClaimTime(historicTaskInstance.getClaimTime());
			
			historicTaskInstanceVo.setDueDate(historicTaskInstance.getDueDate());
			
			historicTaskInstanceVo.setEndTime(historicTaskInstance.getEndTime());
			
			historicTaskInstanceVo.setName(historicTaskInstance.getName());
			
			historicTaskInstanceVo.setOwner(historicTaskInstance.getOwner());
			
			historicTaskInstanceVo.setId(historicTaskInstance.getId());
			
			historicTaskInstanceVoList.add(historicTaskInstanceVo);
			
		}
		return historicTaskInstanceVoList;
	}
	@Override
	public BaseResponse delegateTask(String id,String assignee,String userId) {
		
		Task task=taskService.createTaskQuery().taskId(id).singleResult();
		
		BaseResponse baseResponse=new BaseResponse();
		
		if(!task.getAssignee().equals(assignee)) {
			baseResponse.setFailed(TaskMessages.FAILED_MESSAGE_TASK_NOT_BELONGS_CURRENT_ASSIGNEE.getName());
			return baseResponse;
		}
		
		taskService.delegateTask(id, userId);
		
		baseResponse.setSccucess();

		return baseResponse;
	}
	@Override
    public BaseResponse unclaim(String id,String assignee) {
		
		Task task=taskService.createTaskQuery().taskId(id).singleResult();
		
		BaseResponse baseResponse=new BaseResponse();
		
		if(!task.getAssignee().equals(assignee)) {
			baseResponse.setFailed(TaskMessages.FAILED_MESSAGE_TASK_NOT_BELONGS_CURRENT_ASSIGNEE.getName());
			return baseResponse;
		}
		
		taskService.unclaim(id);
		
		baseResponse.setSccucess();

		return baseResponse;
	}

}
